/*
 *    Copyright (c) 2018-2025, lengleng All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: lengleng (wangiegie@gmail.com)
 */
package com.pig4cloud.pigx.shop.user.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.enums.*;
import com.pig4cloud.pigx.common.core.util.InvitationCodeUtil;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.wechat.WeChatSignatureReqDTO;
import com.pig4cloud.pigx.common.core.util.wechat.WechatGzhAuth;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import com.pig4cloud.pigx.shop.user.api.dto.ShopUserDTO;
import com.pig4cloud.pigx.shop.user.api.entity.*;
import com.pig4cloud.pigx.shop.user.api.vo.ShopUserExcelVO;
import com.pig4cloud.pigx.shop.user.api.vo.ShopUserSalesExcelVO;
import com.pig4cloud.pigx.shop.user.api.vo.ShopUserVO;
import com.pig4cloud.pigx.shop.user.mapper.PromotionChannelMapper;
import com.pig4cloud.pigx.shop.user.mapper.ShopUserMapper;
import com.pig4cloud.pigx.shop.user.service.ShopUserAvatarService;
import com.pig4cloud.pigx.shop.user.service.ShopUserInfoService;
import com.pig4cloud.pigx.shop.user.service.ShopUserNickNameService;
import com.pig4cloud.pigx.shop.user.service.ShopUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.BindingResult;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 商城用户
 *
 * @author pigx code generator
 * @date 2023-11-30 19:47:26
 */
@Slf4j
@Service
@AllArgsConstructor
public class ShopUserServiceImpl extends ServiceImpl<ShopUserMapper, ShopUser> implements ShopUserService {

	private final RedisTemplate redisTemplate;

	private final ShopUserInfoService shopUserInfoService;

	private final PromotionChannelMapper promotionChannelMapper;

	private final ShopUserNickNameService shopUserNickNameService;

	private static final String defaultinvitedCode = "888888";

	private final ShopUserAvatarService shopUserAvatarService;

	// private final WechatGzhAuth wechatGzhAuth;

	/**
	 * 用户注册
	 * @param shopUserDTO
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public String register(ShopUserDTO shopUserDTO) {

		String loginAccount = shopUserDTO.getLoginAccount();

		try {
			Long.parseLong(loginAccount);
		}
		catch (Exception ex) {
			return "无效号码";
		}

		// 短信授权的场合
		if (shopUserDTO.getRegisterModel().equals(RegisterModelEnum.SMS.getType())) {
			Object codeObj = redisTemplate.opsForValue()
					.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + loginAccount);
			if (codeObj != null) {
				if (!shopUserDTO.getSmsCode().equals(codeObj.toString())) {
					return "手机验证码错误";
				}
			}
			else {
				return "手机验证码已失效，请重新获取";
			}
		}
		else {
			// 微信授权
		}

		boolean isExists = checkUserExists(loginAccount);
		if (isExists) {
			log.info("存在：" + loginAccount + "用户");
			return "";
		}

		// 不存在的场合
		log.info("不存在：" + loginAccount + "用户");

		ShopUser parentShopUser = this.getParentShopUser(shopUserDTO.getInvitedCode());
		if (parentShopUser == null) {
			log.info("邀请码:" + shopUserDTO.getInvitedCode());
			return "不存在上级用户，无法注册，请联系客服";
		}

		// 添加用户
		this.createNewUser(parentShopUser, loginAccount, shopUserDTO.getPlatform(), "", "",
				RegisterSourceEnum.MANUAL.getType(), 0, shopUserDTO.getRegisterType());
		return null;
	}

	/**
	 * 判断用户是否存在
	 * @return
	 */
	private boolean checkUserExists(String loginAccount) {
		long count = this.count(Wrappers.<ShopUser>lambdaQuery().eq(ShopUser::getLoginAccount, loginAccount));
		return count > 0;
	}

	/**
	 * 根据邀请码获取用户信息
	 * @return
	 */
	private ShopUser getParentShopUser(String invitedCode) {
		if (StringUtils.isEmpty(invitedCode)) {
			invitedCode = defaultinvitedCode;
		}
		return this.getOne(Wrappers.<ShopUser>lambdaQuery().eq(ShopUser::getInvitedCode, invitedCode));
	}

	/**
	 * 注册新用户
	 * @param parentShopUser
	 * @param loginAccount
	 * @param platform
	 */
	private void createNewUser(ShopUser parentShopUser, String loginAccount, String platform, String realName,
			String shopUserType, String registerSource, Integer pointBalance, String registerType) {
		ShopUser currentUser = new ShopUser();
		currentUser.setChannelCode(parentShopUser.getChannelCode());
		currentUser.setLoginAccount(loginAccount);
		currentUser.setPhone(loginAccount);
		currentUser.setPlatform(platform);

		if (StringUtils.isEmpty(shopUserType)) {
			if (parentShopUser.getShopUserType().equals(ShopUserTypeEnum.NORMAL.getType())) {
				// 上级是普通用户的场合
				currentUser.setShopUserType(ShopUserTypeEnum.NORMAL.getType());
				// 获取上级的销售代表
				currentUser.setSalesShopUserId(parentShopUser.getSalesShopUserId());
			}
			else if (parentShopUser.getShopUserType().equals(ShopUserTypeEnum.SALES.getType())) {
				// 上级是销售代表的场合
				currentUser.setShopUserType(ShopUserTypeEnum.NORMAL.getType());
				// 获取销售代表ID
				currentUser.setSalesShopUserId(parentShopUser.getId());
			}
			else {
				// 属于公海用户
				currentUser.setShopUserType(ShopUserTypeEnum.PUBLIC.getType());
			}
		}
		else {
			currentUser.setShopUserType(shopUserType);
		}

		// 设置父ID
		currentUser.setParentId(parentShopUser.getId());

		// 随机获取用户昵称
		currentUser.setNickName(getUserNick());
		// 真实姓名
		currentUser.setRealName(realName);
		// 设置头像
		currentUser.setHeaderUrl(getHeader());
		// 注册来源
		currentUser.setRegisterSource(registerSource);
		// 注册方式
		currentUser.setRegisterType(registerType);
		// 添加用户
		this.save(currentUser);
		Long shopUserId = currentUser.getId();
		// 邀请码
		currentUser.setInvitedCode(InvitationCodeUtil.gen(shopUserId));
		// 设置层级关系
		currentUser.setPpath(parentShopUser.getPpath() + "/" + shopUserId.toString());
		// 更新用户信息
		this.updateById(currentUser);
		log.info("用户: " + loginAccount + "添加成功");

		// 添加钱包信息
		ShopUserInfo shopUserInfo = new ShopUserInfo();
		shopUserInfo.setShopUserId(currentUser.getId());
		shopUserInfo.setPointBalance(pointBalance);
		shopUserInfo.setCashBalance(0);
		shopUserInfo.setProfitBalance(0);
		shopUserInfo.setFreezePoint(0);
		shopUserInfo.setFreezeProfit(0);
		shopUserInfo.setUseOrderTotal(0);
		shopUserInfo.setUsePointTotal(0);
		shopUserInfo.setExtractCashTotal(0);
		shopUserInfo.setWechatShareFriendsCount(0);
		shopUserInfo.setWechatShareFriendsCircleCount(0);
		shopUserInfoService.save(shopUserInfo);
	}

	/**
	 * 随机获取用户昵称
	 * @return
	 */
	private String getUserNick() {
		String result = "默认昵称";
		try {
			int min = 1; // 最小值
			int max = 1; // 最大值（不包含）
			long count = shopUserNickNameService.count();
			max = (int) count;
			Random random = new Random();
			int randomNum = random.nextInt((max - min)) + min;
			System.out.println("随机生成的数字为：" + randomNum);
			ShopUserNickName shopUserNickName = shopUserNickNameService.getById(randomNum);
			result = shopUserNickName.getNickName();
		}
		catch (Exception ex) {

		}
		return result;
	}

	/**
	 * 随机获取用户昵称
	 * @return
	 */
	private String getHeader() {
		String result = "";
		try {
			int min = 1; // 最小值
			int max = 1; // 最大值（不包含）
			long count = shopUserAvatarService.count();
			max = (int) count;
			Random random = new Random();
			int randomNum = random.nextInt((max - min)) + min;
			System.out.println("随机生成的数字为：" + randomNum);
			ShopUserAvatar shopUserAvatar = shopUserAvatarService.getById(randomNum);
			result = shopUserAvatar.getHeaderUrl();
		}
		catch (Exception ex) {

		}
		return result;
	}

	/**
	 * 获取用户详细信息
	 * @param id
	 * @return
	 */
	@Override
	public ShopUserVO getShopUserInfoByC(Long id) {
		ShopUserVO result = new ShopUserVO();
		ShopUser shopUser = this.getById(id);
		BeanUtils.copyProperties(shopUser, result);

		LambdaQueryWrapper<ShopUserInfo> lqw = new LambdaQueryWrapper<>();
		lqw.eq(ShopUserInfo::getShopUserId, result.getId());
		ShopUserInfo shopUserInfo = shopUserInfoService.getOne(lqw);

		result.setShopUserInfo(shopUserInfo);

		return result;
	}

	/**
	 * 分页获取用户信息
	 * @param shopUserDTO
	 * @return
	 */
	@Override
	public IPage<ShopUserVO> getPage(Page page, ShopUserDTO shopUserDTO) {
		IPage<ShopUserVO> result = new Page<>();

		// 分页查询用户数据
		LambdaQueryWrapper<ShopUser> lqwShopUser = new LambdaQueryWrapper<>();
		lqwShopUser.eq(ShopUser::getShopUserType, shopUserDTO.getShopUserType());
		if (!StringUtils.isEmpty(shopUserDTO.getLoginAccount())) {
			lqwShopUser.like(ShopUser::getLoginAccount, shopUserDTO.getLoginAccount());
		}
		if (!StringUtils.isEmpty(shopUserDTO.getNickName())) {
			lqwShopUser.like(ShopUser::getNickName, shopUserDTO.getNickName());
		}
		lqwShopUser.eq(ShopUser::getDelFlag, DeleteFlagEnum.VALID.getType());
		lqwShopUser.orderByDesc(ShopUser::getCreateTime);
		IPage<ShopUser> items = this.page(page, lqwShopUser);
		if (items.getRecords().size() > 0) {
			List<String> channelCodes = new ArrayList<>();
			List<Long> userIds = new ArrayList<>();
			List<Long> currentUserIds = new ArrayList<>();
			result = items.convert(u -> {
				ShopUserVO v = new ShopUserVO();
				BeanUtils.copyProperties(u, v);
				channelCodes.add(u.getChannelCode());
				if (u.getSalesShopUserId() != null) {
					userIds.add(u.getSalesShopUserId());
				}
				v.setSalesUserList(new ArrayList<>());
				userIds.add(v.getParentId());
				currentUserIds.add(v.getId());
				return v;
			});

			// 去重
			List<String> distinctList = channelCodes.stream().distinct().collect(Collectors.toList());
			// 查询渠道名称
			LambdaQueryWrapper<PromotionChannel> lqwPromotionChannel = new LambdaQueryWrapper<>();
			lqwPromotionChannel.in(PromotionChannel::getChannelCode, distinctList);
			lqwPromotionChannel.eq(PromotionChannel::getDelFlag, DeleteFlagEnum.VALID.getType());
			List<PromotionChannel> promotionChannels = promotionChannelMapper.selectList(lqwPromotionChannel);
			result.getRecords().forEach(item -> {
				Optional<PromotionChannel> promotionChannel = promotionChannels.stream()
						.filter(p -> p.getChannelCode().equals(item.getChannelCode())).findFirst();
				if (promotionChannel.isPresent()) {
					item.setPromotionChannelName(promotionChannel.get().getChannelName());
				}
			});

			// 获取销售代表信息
			if (userIds.size() > 0) {
				List<Long> userIdList = userIds.stream().distinct().collect(Collectors.toList());
				lqwShopUser = new LambdaQueryWrapper<>();
				lqwShopUser.in(ShopUser::getId, userIdList);
				lqwShopUser.eq(ShopUser::getDelFlag, DeleteFlagEnum.VALID.getType());
				List<ShopUser> shopUsers = this.list(lqwShopUser);

				// 获取用户积分，余额等信息
				LambdaQueryWrapper<ShopUserInfo> lqwShopUserInfo = new LambdaQueryWrapper<>();
				lqwShopUserInfo.in(ShopUserInfo::getShopUserId, currentUserIds);
				lqwShopUserInfo.eq(ShopUserInfo::getDelFlag, DeleteFlagEnum.VALID.getType());
				List<ShopUserInfo> shopUserInfos = shopUserInfoService.list(lqwShopUserInfo);

				result.getRecords().forEach(item -> {
					// 获取销售代表信息
					if (item.getSalesShopUserId() != null) {
						Optional<ShopUser> salesUser = shopUsers.stream()
								.filter(p -> p.getId().longValue() == item.getSalesShopUserId().longValue())
								.findFirst();
						if (salesUser.isPresent()) {
							item.getSalesUserList().add(salesUser.get());
						}
					}

					// 获取上级用户信息
					Optional<ShopUser> parentUser = shopUsers.stream()
							.filter(p -> p.getId().longValue() == item.getParentId().longValue()).findFirst();
					if (parentUser.isPresent()) {
						item.setParentUserInfo(parentUser.get());
					}

					// 获取用户余额等信息
					Optional<ShopUserInfo> shopUserInfo = shopUserInfos.stream()
							.filter(p -> p.getShopUserId().longValue() == item.getId().longValue()).findFirst();
					if (shopUserInfo.isPresent()) {
						item.setShopUserInfo(shopUserInfo.get());
					}
				});
			}
		}
		return result;
	}

	/**
	 * 获取用户信息
	 * @param id
	 * @return
	 */
	@Override
	public ShopUserVO getShopUserInfo(Long id) {

		// 获取用户信息
		ShopUserVO result = new ShopUserVO();
		ShopUser shopUser = this.getById(id);
		BeanUtils.copyProperties(shopUser, result);

		result.setSalesUserList(new ArrayList<>());
		// 获取业代信息
		if (result.getSalesShopUserId() != null) {
			ShopUser userSales = this.getById(result.getSalesShopUserId());
			result.getSalesUserList().add(userSales);
		}

		return result;
	}

	/**
	 * 导入销售代表
	 * @param excelVOList
	 * @param bindingResult
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R importUserSales(List<ShopUserSalesExcelVO> excelVOList, BindingResult bindingResult) {
		List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
		ShopUser parentShopUser = this.getParentShopUser("");
		Long index = 0L;
		for (ShopUserSalesExcelVO item : excelVOList) {
			Set<String> errorMsg = new HashSet<>();
			// 判断用户是否存在
			boolean isExists = checkUserExists(item.getLoginAccount());
			// 不存在当前用户的场合
			if (!isExists) {
				// 创建新用户
				this.createNewUser(parentShopUser, item.getLoginAccount(), PlatformEnum.WXAPPLET.getType(),
						item.getRealName(), ShopUserTypeEnum.SALES.getType(), RegisterSourceEnum.EXPORT.getType(), 0,
						"5");
			}
			else {
				errorMsg.add("存在相同的用户--> 手机号: " + item.getLoginAccount() + ", 姓名: " + item.getRealName());
				errorMessageList.add(new ErrorMessage(++index, errorMsg));
			}
		}
		if (CollUtil.isNotEmpty(errorMessageList)) {
			return R.failed(errorMessageList);
		}
		return R.ok();
	}

	/**
	 * 导入用户
	 * @param excelVOList
	 * @param bindingResult
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public R importUser(List<ShopUserExcelVO> excelVOList, BindingResult bindingResult) {
		List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
		Long index = 0L;
		for (ShopUserExcelVO item : excelVOList) {
			Set<String> errorMsg = new HashSet<>();

			boolean isExists = checkUserExists(item.getLoginAccount());
			// 不存在当前用户的场合
			if (!isExists) {
				// 通过销售代表手机号获取销售员信息
				ShopUser parentShopUser = this.getOne(Wrappers.<ShopUser>lambdaQuery()
						.eq(ShopUser::getLoginAccount, item.getSalesShopUserIdLoginAccount())
						.eq(ShopUser::getShopUserType, ShopUserTypeEnum.SALES.getType()));
				if (parentShopUser != null) {
					// 存在销售代表的场合, 创建新用户
					this.createNewUser(parentShopUser, item.getLoginAccount(), PlatformEnum.WXAPPLET.getType(),
							item.getRealName(), "", RegisterSourceEnum.EXPORT.getType(),
							Integer.parseInt(item.getPointBalance()), "5");
				}
				else {
					// 不存在销售代表
					errorMsg.add("不存在销售代表--> 手机号: " + item.getSalesShopUserIdLoginAccount());
					errorMessageList.add(new ErrorMessage(++index, errorMsg));
				}
			}
			else {
				errorMsg.add("存在相同的用户--> 手机号: " + item.getLoginAccount() + ", 姓名: " + item.getRealName());
				errorMessageList.add(new ErrorMessage(++index, errorMsg));
			}
		}
		if (CollUtil.isNotEmpty(errorMessageList)) {
			return R.failed(errorMessageList);
		}
		return R.ok();
	}

	/**
	 * 修改用户昵称
	 * @param shopUser
	 * @return
	 */
	@Override
	public R updateUserNickName(ShopUser shopUser) {
		ShopUser user = this.getById(shopUser.getId());
		if (user == null) {
			return R.failed("当前用户不存在，无法修改昵称");
		}

		ShopUser record = new ShopUser();
		record.setId(shopUser.getId());
		record.setNickName(shopUser.getNickName());
		return R.ok(this.updateById(record));
	}

	/**
	 * 修改用户头像
	 * @param shopUser
	 * @return
	 */
	@Override
	public R updateUserAvatar(ShopUser shopUser) {
		ShopUser user = this.getById(shopUser.getId());
		if (user == null) {
			return R.failed("当前用户不存在，无法修改头像");
		}

		ShopUser record = new ShopUser();
		record.setId(shopUser.getId());
		record.setHeaderUrl(shopUser.getHeaderUrl());
		return R.ok(this.updateById(record));
	}

	/**
	 * 根据销售id获取用户列表
	 * @param page
	 * @param shopUserDTO
	 * @return
	 */
	@Override
	public IPage<ShopUserVO> getUserPageListBySaleUserId(Page page, ShopUserDTO shopUserDTO) {
		IPage<ShopUserVO> result = new Page<>();
		LambdaQueryWrapper<ShopUser> lqwShopUser = new LambdaQueryWrapper<>();
		lqwShopUser.eq(ShopUser::getShopUserType, shopUserDTO.getShopUserType());
		lqwShopUser.eq(ShopUser::getSalesShopUserId, shopUserDTO.getSalesShopUserId());
		if (!StringUtils.isEmpty(shopUserDTO.getLoginAccount())) {
			lqwShopUser.like(ShopUser::getLoginAccount, shopUserDTO.getLoginAccount());
		}
		if (!StringUtils.isEmpty(shopUserDTO.getNickName())) {
			lqwShopUser.like(ShopUser::getNickName, shopUserDTO.getNickName());
		}
		lqwShopUser.orderByDesc(ShopUser::getCreateTime);
		IPage<ShopUser> items = this.page(page, lqwShopUser);
		if (items.getRecords().size() > 0) {
			List<String> channelCodes = new ArrayList<>();
			result = items.convert(u -> {
				ShopUserVO v = new ShopUserVO();
				BeanUtils.copyProperties(u, v);
				channelCodes.add(u.getChannelCode());
				return v;
			});

			// 去重
			List<String> distinctList = channelCodes.stream().distinct().collect(Collectors.toList());
			// 查询渠道名称
			LambdaQueryWrapper<PromotionChannel> lqwPromotionChannel = new LambdaQueryWrapper<>();
			lqwPromotionChannel.in(PromotionChannel::getChannelCode, distinctList);
			lqwPromotionChannel.eq(PromotionChannel::getDelFlag, DeleteFlagEnum.VALID.getType());
			List<PromotionChannel> promotionChannels = promotionChannelMapper.selectList(lqwPromotionChannel);
			result.getRecords().forEach(item -> {
				Optional<PromotionChannel> promotionChannel = promotionChannels.stream()
						.filter(p -> p.getChannelCode().equals(item.getChannelCode())).findFirst();
				if (promotionChannel.isPresent()) {
					item.setPromotionChannelName(promotionChannel.get().getChannelName());
				}
			});
		}
		return result;
	}

	/**
	 * jsapi授权
	 * @param shopUserDTO
	 * @return
	 */
	@Override
	public R getWeChatSignature(ShopUserDTO shopUserDTO) {
		WeChatSignatureReqDTO weChatSignatureReqDTO = new WeChatSignatureReqDTO();
		weChatSignatureReqDTO.setUrl(shopUserDTO.getPageUrl());
		WechatGzhAuth.setRedisTemplate(redisTemplate);
		return WechatGzhAuth.getWeChatSignature(weChatSignatureReqDTO);
	}

}
